package com.example.utils;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @author zhangs
 * @version v1.0
 * @decription 控制并发线程数
 * @date 2021/4/7 22:17
 **/
public class SemaphoreDemo {
    // 事件回调
    interface Action {
        void action();
    }

    static class Task extends Thread {
        Action before;
        Action after;

        public Task(Action before, Action after) {
            this.before = before;
            this.after = after;
        }

        @Override
        public void run() {
            // 任务执行前的回调
            before.action();
            try {
                Random random = new Random();
                Thread t = Thread.currentThread();
                System.out.println(t.getName() + "开始使用数据库！");
                TimeUnit.SECONDS.sleep(random.nextInt(20));
                System.out.println(t.getName() + "结束使用数据库！");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 任务执行后的回调
                after.action();
            }
        }
    }

    public static void main(String[] args) {
        final Semaphore semaphore = new Semaphore(3);
        for (int i = 0; i < 10; i++) {
            // 关闭信号
            new Task(() -> {
                try {
                    // 获取信号
                    semaphore.acquire();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, semaphore::release).start();
        }
    }
}
